import { format as urlFormat } from 'url';
import fetch from 'fermionjs/lib/fetch';
import urlPathConcat from '@kuiper-helpers/url-path-concat/dist';
import pkg from '../../../../package.json';
import errorCodesBuilder from '../../helpers/errorCodesBuilder';

const errorCodes = errorCodesBuilder('移除任务失败');

export default async function removeJob({ context, jobId }) {
	const {
		request: {
			log,
			auth: {
				credentials: { uid, permissionMap },
			},
			server: {
				methods: { balanceTaskCountUpdate, removeTask },
				app: {
					model: { Asset, Job, Task, ResultNumbers, Alert, SitePortrait },
					config: {
						[pkg.name]: { token, serviceApi },
					},
				},
			},
		},
	} = context;

	let job = await Job.findById(jobId).populate('assetId');
	if (!job) return;

	if (
		job.uid.toString() !== uid &&
		!permissionMap[`cloud-monitor\x01removeJob\x010`]
	) {
		const error = errorCodes['[03]不能删除没有所有权的资产'];
		log.error({ error }, error.rawMessage);
		throw error;
	}

	job = job.toObject();
	try {
		log.info({ jobId }, '删除调度任务');
		await removeTask({ jobId });
	} catch (err) {
		const error = errorCodes['[03]deleteTask: 删除Queue任务失败'].from(err);
		log.error({ error, job }, error.rawMessage);
		throw error;
	}

	try {
		await fetch(urlPathConcat(serviceApi, '/api/v2/cloud/udb_del_all'), {
			method: 'POST',
			headers: { cookie: `token=${token}` },
			body: JSON.stringify({
				uid: job.uid,
				job_id: jobId,
			}),
			retry: 3,
		}).catch(error => {
			log.error({ jobId, error, uid: job.uid }, '删除关联云防御加黑失败');
		});
		await Job.deleteOne({ _id: jobId });
		Promise.allSettled([
			Task.deleteMany({ jobId }),
			ResultNumbers.deleteMany({ jobId }),
			Alert.deleteMany({ jobId: job._id }),
			SitePortrait.deleteMany({ jobId }),
			Asset.deleteOne({ jobId: jobId }),
		]).catch(result => {
			log.info({ jobId, result }, '删除资产关联记录');
		});
	} catch (err) {
		const error = errorCodes['[03]deleteResult: 删除历史任务数据失败'].from(
			err
		);
		log.error({ jobId, error }, error.rawMessage);
	}

	balanceTaskCountUpdate(job.uid).catch(err => {
		const error = errorCodes['[03]删除资产: 余额扣除失败'].from(err);
		log.error({ error }, error.rawMessage);
	});

	log.audit(
		{
			jobId,
			affects: [job.targetUrl],
			module: 'job',
			actionType: 'delete',
			actionMessage: '删除资产',
			detail: `删除资产，资产名称：${job.note}，资产地址：${urlFormat({
				protocol: job.target.protocol,
				host: job.target.host,
			})}。`,
		},
		`[${job.target.host}]删除资产`
	);
}
